"""The talk.py module includes all the communication logic between pomares peers."""

import toc, file
from serialize import pack, unpack
from config import my_uuid

def keys_exist(args, keyList):
	"""Returns True if all keys in keyList exist in args."""
	val = True
	for key in keyList:
		val = val and args.has_key(key)

	return val


def to_client(handler):
	"""Decides what to send to a client given a handler object."""

	request_dict = {'LIST':request_LIST, 'FILE':request_FILE, 'PLIST':request_PLIST,
			'RESOLV':request_RESOLV,
	}

	handler.pomares_id = None
	if handler.parsed_args.has_key('pomares_id'):
		handler.pomares_id = handler.parsed_args['pomares_id']
	
	try:
		request_dict[handler.parsed_request](handler)

	except KeyError:
		handler.push_status(400, 'Bad Request')
		pass

def request_LIST(handler):
	tocs = toc.TOC()
	buffer = pack('LIST', tocs.lastUpdates(handler.parsed_pomar))
	handler.push_status(200, 'OK', size=len(buffer))
	handler.push(buffer)


def request_PLIST(handler):
	if keys_exist(handler.parsed_args, ('from', 'to')):
		tocs = toc.TOC()
		buffer = ''
		if handler.pomares_id:
			buffer = pack('PLIST', tocs.listVersion(handler.pomares_id, 
				(handler.parsed_args['from'], handler.parsed_args['to']), handler.parsed_pomar))
		else:
			buffer = pack('PLIST', tocs.listVersion(my_uuid, 
				(handler.parsed_args['from'], handler.parsed_args['to']), handler.parsed_pomar))

		handler.push_status(200, 'OK', size=len(buffer))
		handler.push(buffer)

	else:
		handler.push_status(400, 'Bad Request')


def request_FILE(handler):
	if keys_exist(handler.parsed_args, ('hash', 'chunk')):
		tocs = toc.TOC()
		filename_size = tocs.pathFor(handler.parsed_args['hash'], handler.parsed_pomar)
		
		if filename_size is not None and handler.parsed_args['chunk'].isdigit():
			path, size = filename_size
			producer, length   = file.chunk_producer(path, size, int(handler.parsed_args['chunk']))
			handler.push_status(200, 'OK', size=length)
			handler.push_with_producer(producer)
		else:
			handler.push_status(204, 'No Content')
	else:
		handler.push_status(400, 'Bad Request')


def request_RESOLV(handler):
	if handler.pomares_id:
		resolv = toc.Resolver()
		who = resolv.resolve(handler.pomares_id)

		if who:
			buffer = pack('RESOLV',(handler.pomares_id, who))
			handler.push_status(200, 'OK', size=len(buffer))
			handler.push(buffer)
		else:
			handler.push_status(204, 'No Content')
	else:
		handler.push_status(400, 'Bad Request')
		
			
